package utils

import (
	"fmt"
	"os"
)

type LoggerFileWriter struct {
	// The opened file
	filenamefmt string
	file        *os.File

	lastfilename string

	// The logging format
	format         string
	logLvl         LogLevel
	logLvlOp       LogOp // 0:= 1:>=, 2:<=
	curr_file_size int64
	max_file_size  int64
}

func NewLoggerFileWriter(fnamefmt string) *LoggerFileWriter {
	rval := &LoggerFileWriter{
		filenamefmt:    fnamefmt,
		format:         "[%D %T] [%L] %M (%S)\r\n",
		curr_file_size: 0,
		logLvl:         LogLV_0,
		logLvlOp:       LogOp_ALL,
	}
	ForceCreateFilePath(fnamefmt)
	return rval
}

func (this *LoggerFileWriter) SetMsgFormat(fmt string) *LoggerFileWriter {
	this.format = fmt
	return this
}

func (this *LoggerFileWriter) ConfigMaxFileSize(val int64) *LoggerFileWriter {
	this.max_file_size = val
	return this
}

func (this *LoggerFileWriter) SetLvlFilter(lvl LogLevel, matchOp LogOp) *LoggerFileWriter {
	this.logLvl = lvl
	this.logLvlOp = matchOp
	return this
}

func (this *LoggerFileWriter) checkFile(rec *LogRecord) error {
	f1 := string(FormatLogRecord(this.filenamefmt, rec))

	if this.lastfilename == f1 {
		return nil
	}

	if this.file != nil {
		this.file.Close()
		this.file = nil
	}

	// 检测新文件是否存在,如果存在则进行更名
	err := CheckRotateFile(f1)
	if err != nil {
		return err
	}
	err = ForceCreateFilePath(f1)
	if err != nil {
		return err
	}

	fd, err := os.OpenFile(f1, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660)
	if err != nil {
		return err
	}

	this.lastfilename = f1
	this.file = fd
	return nil
}

func (this *LoggerFileWriter) LogWrite(rec *LogRecord) {
	if !IsFilter(this.logLvl, this.logLvlOp, rec) {
		return
	}

	// FileLogWriter("E:\\ylbs\\jt-app/log/app"): CheckRotateFile Rename: rename E:\ylbs\jt-app/log/app-JT808.log E:\ylbs\jt-app/log/app-JT808.log.1: The process cannot access the file because it is being used by another process.
	err := this.checkFile(rec)
	if err != nil {
		fmt.Fprintf(os.Stderr, "[%s]FileLogWriter(%s): %s\n", NowString(), this.filenamefmt, err)
		return
	}

	msg := string(FormatLogRecord(this.format, rec))
	n, err := fmt.Fprint(this.file, msg)
	if err != nil {
		fmt.Fprintf(os.Stderr, "[%s]FileLogWriter(%s): %s\n", NowString(), this.filenamefmt, err)
		return
	}

	this.curr_file_size += int64(n)
	if this.max_file_size > 0 && this.curr_file_size >= this.max_file_size {
		this.Close()
		this.curr_file_size = 0
		this.lastfilename = "" // 下次新建文件
	}
}

func (this *LoggerFileWriter) Close() {
	if this.file != nil {
		this.file.Close()
		this.file = nil
	}
}
